package com.sparkseries.common.util.redis;


import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtils {
    /**
     * 默认过期时长一天
     */
    private final static long DEFAULT_EXPIRE = 60 * 60 * 24L;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    // String类型
    public void set(String key, Object value) {
        set(key, value, DEFAULT_EXPIRE);
    }


    // String类型，设置过期时长
    public void set(String key, Object value, long expire) {
        redisTemplate.opsForValue().set(key, value);
        expire(key, expire);
    }

    // String类型，查询
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    // String类型，查询设置过期时长
    public Object get(String key, long expire) {
        expire(key, expire);
        return redisTemplate.opsForValue().get(key);
    }

    // 获取匹配指定模式的所有键
    public Set<String> getKeysByPattern(String pattern) {
        return redisTemplate.keys(pattern);
    }

    // 删除
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    public void delete(Collection<String> keys) {
        redisTemplate.delete(keys);
    }

    public void deleteByPattern(String pattern) {
        redisTemplate.delete(getKeysByPattern(pattern));
    }

    // 设置过期时长
    public void expire(String key, long expire) {
        redisTemplate.expire(key, expire, TimeUnit.SECONDS);
    }

    public void hashPut(String key, Object hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    public void hashGet(String key, Object hashKey) {
        redisTemplate.opsForHash().get(key, hashKey);
    }

    public Long leftPush(String key, Object object) {
        return redisTemplate.opsForList().leftPush(key, object);
    }

    public Object rightPop(String key) {
        return redisTemplate.opsForList().rightPop(key);
    }

    // 公共的从 Redis 中获取缓存数据的方法
    private <T> T getCacheData(String key, Class<T> type) {
        Object data = get(key);
        if (!ObjectUtils.isNull(data) && type.isAssignableFrom(data.getClass())) {
            return type.cast(data);
        }
        return null;
    }

    // 尝试从 Redis 中获取单个缓存数据
    public <R> R getByCache(String key, Class<R> type) {
        return getCacheData(key, type);
    }

    // 尝试从 Redis 中获取列表缓存数据
    public <R> List<R> getListByCache(String key, Class<R> type) {
        return getCacheData(key, (Class<List<R>>) (Class<?>) List.class);
    }
}
